import { BaseManager } from './../libs/rxjs/cc3/BaseManager';
import { _decorator, director, color, System, JsonAsset, Prefab, instantiate, assetManager, Node, SpriteFrame } from 'cc';
import { bundleLoad, bundleLoadDir, bundlePreloadDir } from '../libs/rxjs/cc3/AssetManagerLoad';
import { concat, map, of } from 'rxjs';
const { ccclass, property } = _decorator;

const gameAssetsList = [
]

@ccclass('BundleAssetsManager')
export class BundleAssetsManager extends BaseManager {

    public static instance: BundleAssetsManager;
    static ID = 'bundle_assets_system';
    get logColorOverride() { return color().fromHEX('#FFDDCC') };

    static registerSystem() {
        director.unregisterSystem(director.getSystem(BundleAssetsManager.ID));
        director.registerSystem(BundleAssetsManager.ID, bam, System.Priority.MEDIUM);
        bam.init();
    }

    onInitManager() {
        this.log('onInitManager', this.timestamp);
    }

    jsonAsset: Record<string, JsonAsset> = {};

    loadJson() {
        return bundleLoadDir('ab_config', 'Json', JsonAsset).pipe(map(_ => {
            const { err, data } = _;
            (<JsonAsset[]>data).forEach(_ => {
                this.jsonAsset[_.name] = _;
            });
        }));
    }

    xlsxJsonAssets: Record<string, JsonAsset> = {};

    loadXlsx(assetbundleName: string, path: string) {
        return bundleLoadDir(assetbundleName, path, JsonAsset).pipe(map(_ => {
            const { err, data } = _;
            (<JsonAsset[]>data).forEach(_ => {
                this.xlsxJsonAssets[_.name] = _;
            });
        }));
    }

    loadGameAssetsRefs(assetbundleName: string, path: string, parent: Node, onProgress?: (args: any) => void) {
        return bundleLoad(assetbundleName, path, Prefab, onProgress).pipe(map(_ => {
            const { err, data } = _;
            const prefab = data as Prefab;
            const node = instantiate(prefab);
            node.setParent(parent);
            return node;
        }));
    }

    // exp: 如果sprite本身引用的有这个值，再次赋值这个值，就会出错？！(不要使用这个函数)
    styleIDs = [1, 0]; // 选用优先级
    spriteFrames: Record<string, SpriteFrame> = {};
    loadSpriteFrames(onProgress?: (args: any) => void) {
        const obs = [];
        this.styleIDs.reverse().forEach(id => {
            const ob = bundleLoadDir('texture-1', `style${id}`, SpriteFrame, onProgress).pipe(map(_ => {
                const { err, data } = _;
                data.forEach((sf, idx) => {
                    // this.log('@loadSpriteFrame', sf, idx);
                    this.spriteFrames[sf.name] = sf; // 不带id标签的会按照优先级进行覆盖
                    this.spriteFrames[`${sf.name}#${id}`] = sf;
                });
            }));
            obs.push(ob);
        });
        return concat(...obs);
    }

}

globalThis.BundleAssetsManager = BundleAssetsManager;

export const bam = BundleAssetsManager.instance = new BundleAssetsManager();